﻿using System;
using System.Collections.Generic;
using System.IO;
using Assets.Editor.XmlBufFile;
using UnityEditor;

public class XmltransformBuf
{
    [MenuItem("H3D/资源规范检查/xml转二进制", false, 100)]
    private static void BuildXmlBinaryRun()
    {
        BuildXmlBinaryBat();
    }

    #region new

    public static string GetTargetFolder()
    {
        return Path.Combine(FileUtil.GetRootPath(EnumFileType.STREAMING_ASSETS), Consts.LOGIC_TARGET_CONFIG_DIR);
    }

    public static string GetSourceFolder()
    {
        return Path.Combine(FileUtil.GetRootPath(EnumFileType.STREAMING_ASSETS), Consts.LOGIC_SOURCE_CONFIG_DIR);
    }

    public static bool BuildXmlBinaryBat(bool isAutoSubmitP4 = false, bool isForce = false)
    {
        // 执行转换二进制
        var sourcePath = GetSourceFolder();
        var targetPath = GetTargetFolder();
        var sourceFiles = new List<string>();
        sourceFiles.AddRange(Directory.GetFiles(sourcePath, "*.xml", SearchOption.AllDirectories));
        XMLObjectRegisterForEditor.ResetInEditor();
        XMLObjectRegisterForEditor.RegistAllObject(true, sourcePath);

        var file_lists = new Dictionary<string, HashSet<string>>();
        file_lists.Add("xml", XMLObjectRegisterForEditor.GetAllParserPath());

        var succeedConvertFiles = new List<string>();
        var failedConvertFile = new List<string>();
        float workproc = 0;

        foreach (var item in file_lists)
        {
            var file_list = item.Value;
            var suffix = item.Key;
            var dot_suffix_bytes = ".bytes";

            foreach (var configPath in file_list)
            {
                var absXmlFilePath = Path.GetFullPath(Path.Combine(sourcePath, configPath));
                var binaryFilePath = Path.GetFullPath(Path.Combine(targetPath, configPath) + dot_suffix_bytes);
                var assets = new List<string>();
                assets.Add(configPath);

                if (File.Exists(absXmlFilePath))
                {
                    if (BuildCfgBinaryFile(absXmlFilePath, configPath, binaryFilePath, suffix))
                    {
                        succeedConvertFiles.Add(configPath);
                    }
                    else
                    {
                        failedConvertFile.Add(configPath);
                    }
                }
                else
                {
                    failedConvertFile.Add(configPath);
                }

                sourceFiles.Remove(absXmlFilePath);
                workproc++;
                if ((int) workproc % 20 == 0)
                {
                    EditorUtility.DisplayProgressBar("转换二进制", configPath, workproc / file_list.Count);
                }
            }
        }

        EditorUtility.ClearProgressBar();

        if (failedConvertFile.Count > 0)
        {
            LogWrapper.LogError("转换二进制存在错误");
            return false;
        }

        LogWrapper.LogError("转换完成");
        return true;
    }

    private static bool BuildCfgBinaryFile(string fullpath, string filepath, string binaryFilePath, string suffix)
    {
        switch (suffix)
        {
            case "xml":
                return BuildXmlBinaryFile(fullpath, filepath, binaryFilePath);
        }

        return false;
    }

    public static bool BuildXmlBinaryFile(string fullpath, string filepath, string binaryFilePath)
    {
        try
        {
            var binaryFileFolder = Path.GetDirectoryName(binaryFilePath);
            if (!Directory.Exists(binaryFileFolder))
            {
                Directory.CreateDirectory(binaryFileFolder);
            }

            byte[] bytValue = { };
            var rootNode = XmlHelper.ReadXML(fullpath, ref bytValue);
            if (rootNode == null)
            {
                return false;
            }

            var parserInfo = XMLObjectRegisterForEditor.FindParser(filepath);
            if (parserInfo == null)
            {
                return false;
            }

            var obj = parserInfo.m_parser.ParserXML(rootNode, bytValue);

            if (!XMLBufFileWritter.TransformObj(obj, filepath, fullpath, binaryFilePath))
            {
                LogWrapper.LogError("XmlHelper.TransformObj error ", filepath);
                return false;
            }
        }
        catch (Exception ex)
        {
            LogWrapper.LogError("二进制转换失败: ", ex.Message, ", path: ", fullpath);
            return false;
        }

        return true;
    }

    #endregion
}